# 运行本脚本之前，需要安装一些python库，输入以下命令进行安装
# pip install colorama
# pip install pyperclip

import json
import os
import re
import subprocess
import sys
import urllib.parse
import uuid

import pyperclip
import requests
from colorama import init, Fore, Style


def get_logLocation():
    logLocation = os.getenv('userprofile') + r'\AppData\LocalLow\miHoYo\ZenlessZoneZero'
    logLocationChina = os.getenv('userprofile') + r'\AppData\LocalLow\miHoYo\绝区零'
    if len(sys.argv) > 1:
        if sys.argv[1] == r'global':
            return logLocation
    return logLocationChina


def get_gamedir(logLocation):
    log_path = f'{logLocation}\\Player.log'
    if os.path.exists(log_path):
        with open(log_path, encoding='utf-8') as f:
            line = ''
            for i in range(11):
                line_tmp = f.readline()
                if line is None:
                    break
                line = line + line_tmp
    else:
        log_path = f'{logLocation}\\Player-prev.log'
        if os.path.exists(log_path):
            with open(log_path, encoding='utf-8') as f:
                line = ''
                for i in range(11):
                    line_tmp = f.readline()
                    if line_tmp is None:
                        break
                    line = line + line_tmp
        else:
            print(
                f'{Fore.RED}找不到绝区零日志文件，请确保游戏安装路径没有中文且打开调频历史界面一次{Style.RESET_ALL}')
            exit(0)
    for i in line.split('\n'):
        game_path = re.match(r'\[Subsystems] Discovering subsystems at path (.:/.+ZenlessZoneZero_Data)', i)
        if game_path is not None:
            return game_path[1]
    print(f'{Fore.RED}找不到绝区零日志文件，请确保游戏安装路径没有中文且打开调频历史界面一次{Style.RESET_ALL}')
    exit(0)


def get_cacheFile(game_path):
    cache_path = f'{game_path}/webCaches'
    if not os.path.exists(cache_path):
        print(f'{Fore.RED}找不到绝区零缓存文件，请至少打开调频历史界面一次{Style.RESET_ALL}')
        exit(0)
    folders = [f for f in os.listdir(cache_path) if os.path.isdir(os.path.join(cache_path, f))]
    version_folders = []
    for folder in folders:
        try:
            # 将文件夹名转换为tuple形式的版本号
            version = tuple(map(int, folder.split('.')))
            version_folders.append((version, folder))
        except ValueError:
            # 忽略非版本号格式的文件夹
            continue
    if len(version_folders) == 0:
        print(f'{Fore.RED}找不到绝区零缓存文件，请至少打开调频历史界面一次{Style.RESET_ALL}')
        exit(0)
    cache_path = f'{cache_path}/{max(version_folders)[1]}/Cache/Cache_Data/data_2'
    return cache_path


def get_link(cache_path):
    if not os.path.exists(cache_path):
        print(f'{Fore.RED}找不到绝区零缓存文件，请至少打开调频历史界面一次{Style.RESET_ALL}')
        exit(0)
    tmpFile = os.getenv('TEMP') + f'\\{str(uuid.uuid4())}'
    subprocess.run(["powershell.exe", "-Command", f'copy "{cache_path}" "{tmpFile}"'], capture_output=True,
                   text=True, shell=True)
    # shutil.copy(cache_path, tmpFile)
    if not os.path.exists(tmpFile):
        print(f'{Fore.RED}绝区零缓存文件复制失败，请重试{Style.RESET_ALL}')
        exit(0)
    with open(tmpFile, encoding='utf-8', errors='ignore') as f:
        cachefile_text = f.read()
    os.remove(tmpFile)
    cachefile_text_parts = cachefile_text.split('1/0/')
    if len(cachefile_text_parts) == 0:
        print(f'{Fore.RED}绝区零缓存文件中找不到调频链接，请至少打开调频历史界面一次{Style.RESET_ALL}')
        exit(0)
    link = None
    for i in range(len(cachefile_text_parts) - 1, -1, -1):
        link = re.match(r'http.+getGachaLog[\w%?&\-=.]*', cachefile_text_parts[i])
        if link is not None:
            break
    if link is None:
        print(f'{Fore.RED}绝区零缓存文件中找不到调频链接，请至少打开调频历史界面一次{Style.RESET_ALL}')
        exit(0)
    parsed_url = urllib.parse.urlparse(link[0])
    query_dict = urllib.parse.parse_qs(parsed_url.query)
    params_to_keep = ['authkey', 'authkey_ver', 'sign_type', 'game_biz', 'lang']
    filtered_query_dict = {k: v for k, v in query_dict.items() if k in params_to_keep}
    filtered_query = urllib.parse.urlencode(filtered_query_dict, doseq=True)
    filtered_url = urllib.parse.urlunparse(
        (parsed_url.scheme, parsed_url.netloc, parsed_url.path, parsed_url.params, filtered_query, parsed_url.fragment))
    return filtered_url


def verify_link(link):
    response = requests.get(link)
    text_json = json.loads(response.text)
    if text_json['retcode'] == 0:
        return True
    return False


def main():
    init(autoreset=True)
    print(f'{Fore.GREEN}正在获取抽卡分析链接...\n{Style.RESET_ALL}')
    logLocation = get_logLocation()
    game_path = get_gamedir(logLocation)
    cache_path = get_cacheFile(game_path)
    link = get_link(cache_path)
    if verify_link(link):
        pyperclip.copy(link)
        print(f'{link}\n')
        print(f'{Fore.GREEN}抽卡分析地址获取成功，已自动复制到剪贴板{Style.RESET_ALL}')
    else:
        print(f'{Fore.RED}抽卡链接已失效，请至少打开调频历史界面一次获取新链接地址{Style.RESET_ALL}')


if __name__ == '__main__':
    main()
